package cn.ges.movie.filter

import cn.ges.json.JsonUtil
import com.ges.common.config.jwt.JwtUtil
import com.ges.common.config.jwt.UserSigningKeyResolver
import com.ges.common.vo.ReturnJsonVO
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.authority.AuthorityUtils
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.web.filter.GenericFilterBean
import java.io.IOException
import javax.servlet.FilterChain
import javax.servlet.ServletRequest
import javax.servlet.ServletResponse
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 *
 * @author gespent@163.com
 * @date 2021/3/2 10:50
 */

open class JwtAuthenticationFilter(private val userSigningKeyResolver: UserSigningKeyResolver) : GenericFilterBean() {

    private val log: Logger = LoggerFactory.getLogger(this.javaClass)

    companion object {
        const val HEADER_STRING = "Authorization"
    }

    override fun doFilter(request: ServletRequest, response: ServletResponse, filterChain: FilterChain) {
        request as HttpServletRequest
        try {
            val sign = JwtUtil.sign(request.getHeader(HEADER_STRING), userSigningKeyResolver)
            sign?.let {
                // 得到 权限（角色）
                val authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(it["authorities"] as String?)
                val userId = it.subject
                // 返回验证令牌
                SecurityContextHolder.getContext().authentication = UsernamePasswordAuthenticationToken(userId, null, authorities)
            }

        } catch (e: Exception) {
            e.printStackTrace()
            // JWT 验证异常 直接返回
            val response1 = response as HttpServletResponse
            response1.setHeader("Content-Type", "application/json;charset=UTF-8")
            response1.status = 200
            val objectToJson = JsonUtil.objectToJson(ReturnJsonVO.build(403, null, "用户登录信息已失效，请重新登录!"))
            response.writer.println(objectToJson)
            return
        }
        try {
            filterChain.doFilter(request, response)
        } catch (e: IOException) {
            log.info("IOException:[{}],请求地址为[{}]", e.message, request.requestURI)
        }
    }

}